load("config.asc");
 
/**
 * @requires TraceUtils to trace complex objects
 */
load("TraceUtils.asc");

/**
 * @requires NetServices to communicate with AMFPHP
 * which is located in the scriptlib of FMS
 */
load("netservices.asc");

/**
 *
 */
load("SharedObjectHistory.asc");

/**
 *
 */
load("LiveSessionCallLogger.asc");

/**
 * Handles application start events.
 */
application.onAppStart = function(){
	trace("KNOWBANDLIVE: Application started.");
	// The id of the current livesession.
	this.liveSessionId;
	// Owner
	this.ownerClient;
	// True when the startLiveSession is called.
	this.liveSessionStarted = false;
	// True when the allowParticipants is called which means that users
	// can also login to the session
	this.liveSessionAvailable = false;
	// Holds the SharedObjectHistory items
	this.sharedObjectHistoryHash = new Object();
	// Logger class to save all calls broadcastet between clients. 
	this.liveSessionCallLogger = new LiveSessionCallLogger();
	// A helper clas for pretty print trace outputs
	this.traceUtils = new TraceUtils();
	// AMF Service
	NetServices.setDefaultGatewayUrl(__AMFPHPURL);
	this.serviceConnection = NetServices.createGatewayConnection();
	this.amfService = this.serviceConnection.getService(__AMFPHPSERVICE, this);
	// Timer Ids
	this.nobodyHereId = -1;
	this.ownerIsNotHereId = -1;
}

/**
 * Handles application stop events.
 */
application.onAppStop = function () {
	trace("KNOWBANDLIVE: Application stopped.");
}


application.onConnect = function(clientObj, userId, sessionId, userConfig) {
	
	// TODO: Check the user id and session data.
	
	
	// Is the user already connected?
	for(i = 0; i < this.clients.length; i++) {
	    if(this.clients[i].userId == userId && this.clients[i].ping()) {
			trace("KNOWBANDLIVE: User with the ID " + userId + " already connected. First connection will be closed.");
			this.clients[i].droppedUser = true;
			application.disconnect(this.clients[i]);
			break;
		}
	}
	
	trace("KNOWBANDLIVE: User connected and accepted with the following data:");
	clientObj.userId = userId;
	clientObj.sessionId = sessionId;
	clientObj.userConfig = userConfig;
	trace(this.traceUtils.traceString(clientObj,"\tUser",1,""));
	
	if(userConfig.isOwner) {
		this.ownerClient = clientObj;
	}
	
	
	//this.amfService.checkSession(sessionId);
	// No problem with the user, accept it.
	application.acceptConnection(clientObj);
	
	// Reset timers
	if(this.nobodyHereId > -1) {
		clearInterval(this.nobodyHereId);
		this.nobodyHereId = -1;
	}
	if(this.ownerIsNotHereId > -1) {
		clearInterval(this.ownerIsNotHereId);
		this.ownerIsNotHereId = -1;
	}
	
	// Broadcast this to other users...
	// We use a workaround of setInterval so that FMS broadcasts the message.
	application["connectTimerFor"+clientObj.userId] = setInterval(function (id,userConfig) {application.gatewaySOSend("liveSessionModuleBase", "joinLiveSession", [userConfig]);clearInterval(application["connectTimerFor"+id])}, 100, clientObj.userId, clientObj.userConfig);
}

application.onDisconnect = function(clientObj){
	trace("KNOWBANDLIVE: " + clientObj.userConfig.fullName + " disconnected.");
	if(clientObj.droppedUser != true) {
		application["disconnectTimerFor"+clientObj.userId] = setInterval(function (id) {application.gatewaySOSend("liveSessionModuleBase", "leaveLiveSession", [id]);clearInterval(application["disconnectTimerFor"+id])}, 100, clientObj.userId);
	} else {
		trace("KNOWBANDLIVE: Old connection of " + clientObj.userConfig.fullName + " is dropped.");
	}
	if(this.nobodyHereId > -1) {
		clearInterval(this.nobodyHereId);
		this.nobodyHereId = -1;
	}
	if(this.ownerIsNotHereId > -1) {
		clearInterval(this.ownerIsNotHereId);
		this.ownerIsNotHereId = -1;
	}
	
	if(this.clients.length == 0) {
		this.nobodyHereId = setInterval(application.closeApplication,__NOBODYISHERETIMEOUT);
	} else {
		var found = false;
		for(i = 0; i < this.clients.length; i++) {
			if(this.clients[i].userConfig.isOwner == true) {
				found = true;
				break;
			}
		}
		if(found == false) {
			this.ownerIsNotHereId = setInterval(application.closeApplication,__OWNERISNOTHERETIMEOUT);
		}
	}
}


application.onConnectReject = function(clientObj) {
	trace("KNOWBANDLIVE: Client is rejected.");
}

application.gatewaySOSend = function (soName, funcName, parameters) {
	trace("KNOWBANDLIVE: gatewaySOSend for the function " + funcName + " of " + soName + ".");
	// First broadcast then save call...
	this.broadcastMsg("gatewaySOReceive", soName, funcName, parameters);
	if(this.sharedObjectHistoryHash[soName] == undefined) {
		so = this.sharedObjectHistoryHash[soName] = new SharedObjectHistory(soName);
	} else {
		so = this.sharedObjectHistoryHash[soName];
	}
	so.addCall(funcName, parameters);
	// And  finally log the call...
	this.liveSessionCallLogger.logCall(soName, funcName, parameters);
}

application.closeApplication = function() {
	trace("KNOWBANDLIVE: closeApplication");
	clearInterval(application.closeApplicationSetIntervalId);
	if(application.liveSessionAvailable) {
		application.liveSessionCallLogger.finishAndSave();
		application.amfService.endLiveSession(application.ownerClient.sessionId, application.liveSessionId);
	}
}

application.endLiveSession_Result = function(result) {
	trace("KNOWBANDLIVE: Live Session " + this.liveSessionId + " is successfully ended.");
	this.shutdown();
}

/**
 * Starts logging the live session.
 */
Client.prototype.startLiveSession = function (metadata) {
	if(application.liveSessionStarted == false) {
		trace("KNOWBANDLIVE: Live Session started for the '" + metadata[0].title + "' with the id " + metadata[0].liveSessionId + ".");
		application.liveSessionId = metadata[0]['liveSessionId'];
		application.liveSessionCallLogger.start(metadata);
		application.liveSessionStarted = true;
		return true;
	}
	return false;
}

Client.prototype.allowParticipants = function () {
  if(application.liveSessionAvailable == false) {
    trace("KNOWBANDLIVE: Live Session is available to the participants, now.");
    application.totalPausedTime = 0;
    application.startMilliseconds = Date.now();
    callMilliseconds = application.startMilliseconds - application.liveSessionCallLogger.startMilliseconds;
    application.liveSessionCallLogger.logFile.write("\t\t<liveSessionIsAvailableNow time='" + callMilliseconds + "'/>\n");
    application.liveSessionAvailable = true;
    return 0;
	} else {
    return Date.now() - application.startMilliseconds - application.totalPausedTime;
	}
}

Client.prototype.getCalls = function (soName, funcName, last) {
	trace("KNOWBANDLIVE: Getting calls of " + soName + " with the parameters funcName=" + funcName + " and last=" + last);
	so = application.sharedObjectHistoryHash[soName];
	if(so == undefined) {
		return null;
	}
	return so.getCalls(funcName, last);
}

Client.prototype.gatewaySOSend = function (soName, funcName, parameters) {
	application.gatewaySOSend(soName, funcName, parameters);
}

Client.prototype.pauseLiveSession = function () {
	trace("KNOWBANDLIVE: Live Session paused.");
	application.pausedTime = Date.now();
	application.gatewaySOSend("liveSessionModuleBase", "liveSessionPaused");
}

Client.prototype.resumeLiveSession = function () {
	trace("KNOWBANDLIVE: Live Session resumed.");
	application.totalPausedTime += Date.now() - application.pausedTime;
	application.pausedTime = 0;
	application.gatewaySOSend("liveSessionModuleBase", "resumeLiveSession");
}

Client.prototype.endLiveSession = function () {
	trace("KNOWBANDLIVE: Live Session ended.");
	/*var my_lv = new LoadVars();
	my_lv.klfFile = application.liveSessionCallLogger.filename;
	my_lv.liveSessionId = application.liveSessionId;
	my_lv.send(__CREATERECORDEDSESSIONURL);*/
	application.closeApplicationSetIntervalId = setInterval(application.closeApplication,3000);
}

